package com.koron.order.linepatrol.base.business.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.OrderItem;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.CommonUtils;
import com.koron.order.common.bean.base.OrderType;
import com.koron.order.common.bean.po.OrderSignBean;
import com.koron.order.common.service.OrderSignService;
import com.koron.order.common.util.DateUtils;
import com.koron.order.defect.bean.dto.DefectEquipmentDto;
import com.koron.order.defect.bean.po.DefectBean;
import com.koron.order.defect.bean.query.DefectQuery;
import com.koron.order.defect.service.DefectService;
import com.koron.order.linepatrol.base.bean.convertor.LinePatrolConvertor;
import com.koron.order.linepatrol.base.bean.dto.EquipmentHisDto;
import com.koron.order.linepatrol.base.bean.dto.PatrolDto;
import com.koron.order.linepatrol.base.bean.po.*;
import com.koron.order.linepatrol.base.bean.query.PatrolQuery;
import com.koron.order.linepatrol.base.bean.vo.*;
import com.koron.order.linepatrol.base.business.mapper.PatrolBusinessMapper;
import com.koron.order.linepatrol.base.business.service.PatrolBusinessService;
import com.koron.order.linepatrol.base.service.*;
import com.koron.order.linepatrol.feign.PlanLineOrderMsgFeign;
import com.koron.order.overhaul.feign.EquipmentFeign;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @ClassName PatrolBusinessServiceImpl
 * @description
 * @Author zhouj
 * @Date 2021/10/26 15:50
 */
@Slf4j
@Service("linePatrolBusinessService")
public class PatrolBusinessServiceImpl implements PatrolBusinessService {

    @Autowired
    PatrolService linePatrolService;

    @Autowired
    PatrolUserService linePatrolUserService;

    @Autowired
    OrderSignService orderSignService;

    @Autowired
    PatrolPointService linePatrolPointService;

    @Autowired
    PatrolEquipmentService linePatrolEquipmentService;

    @Autowired
    PatrolEnvCheckService linePatrolEnvCheckService;

    @Autowired
    PatrolEquipmentItemService linePatrolEquipmentItemService;

    @Autowired
    PatrolEquipmentParamsService linePatrolEquipmentParamsService;

    @Autowired
    LinePatrolConvertor linePatrolConvertor;

    @Autowired
    DefectService defectService;

    @Autowired
    private PlanLineOrderMsgFeign planLineOrderMsgFeign;

    @Autowired
    private EquipmentFeign equipmentFeign;

    @Override
    @TaskAnnotation("insertOrUpdate")
    public String insertOrUpdate(SessionFactory factory, PatrolDto patrolDto) {
        return insert(factory, patrolDto, false);
    }

    @Override
    @TaskAnnotation("insert")
    public String insert(SessionFactory factory, PatrolDto patrolDto, boolean isInsert) {
        Boolean updateFlag = true;
        List<PatrolEnvCheckPo> envCheckPoList = new ArrayList<>();
        List<PatrolEquipmentPo> equipmentPoList = new ArrayList<>();
        List<PatrolEquipmentItemPo> equipmentItemPoList = new ArrayList<>();
        List<PatrolEquipmentParamsPo> equipmentParamsPoList = new ArrayList<>();

        //1. 基础信息
        PatrolPo patrolPo = linePatrolConvertor.PatrolDtoToPo(patrolDto);
        if (StringUtils.isEmpty(patrolPo.getId())) {
            //巡视工单id为空 说明新建,后续所有的表主键都要重新赋值
            patrolPo.setId(CodeTools.getCode32());
            updateFlag = false;
        }
        //巡视工单id
        String patrolId = patrolPo.getId();

        //巡视工单签名信息
        if (patrolDto.getMustSign() != null && patrolDto.getMustSign() == 1) {
            //完成时必须签名
            List<OrderSignBean> signBeanList = patrolDto.getSignBeanList();
            if (CollectionUtils.isNotEmpty(signBeanList)) {
                for (OrderSignBean orderSignBean : signBeanList) {
                    orderSignBean.setOrderId(patrolId);
                    orderSignBean.setOrderType(OrderType.PATROL);
                }
                orderSignService.deleteByOrderId(factory, patrolId);
                orderSignService.insertBatch(factory, signBeanList);
            }
        }

        //2.巡视人员信息
        List<PatrolUserPo> userPos = patrolDto.getUserPos();
        if (CollectionUtils.isNotEmpty(userPos)) {
            userPos.forEach(p -> {
                if (StringUtils.isEmpty(p.getId())) {
                    p.setId(CodeTools.getCode32());
                }
                p.setPatrolId(patrolId);
            });
        }

        //3.巡视点信息
        List<PatrolPointVo> pointVos = patrolDto.getPointVos();
        // Assert.notEmpty(pointVos, "巡视点不能为空");
        if (pointVos == null) {
            pointVos = new ArrayList<>();
        }
        if (updateFlag) {
            //当更新的时候,根据更新的标记,修改要更新的清单,防止数据覆盖。
            PatrolDto patrolDto1Old = this.queryPatrolAllDtoByOrderId(factory, patrolId);
            List<PatrolPointVo> pointVosOld = patrolDto1Old.getPointVos();
            for (int i = 0; i < pointVos.size(); i++) {
                //不需要更新的，用旧数据替代
                if (!pointVos.get(i).getNeedUpdate()) {
                    for (PatrolPointVo patrolPointVoOld : pointVosOld) {
                        if (StringUtils.equalsIgnoreCase(patrolPointVoOld.getId(), pointVos.get(i).getId())) {
                            pointVos.set(i, patrolPointVoOld);
                            break;
                        }
                    }
                }
            }
        }

        pointVos.forEach(p -> {
            if (StringUtils.isEmpty(p.getId())) {
                p.setId(CodeTools.getCode32());
            }
            //设置默认巡视状态
            if (StringUtils.isEmpty(p.getStatus())) {
                p.setStatus(PatrolStatus.WAIT_PATROL.getStatus());
            }
            //设置默认签到状态
            if (Objects.isNull(p.getArriveStatus())) {
                p.setArriveStatus(0);
            }
            p.setPatrolId(patrolId);

            //巡视点id
            String patrolPointId = p.getId();
            //3.1 环境检查信息
            List<PatrolEnvCheckVo> envCheckVos = p.getEnvCheckVos();
            if (CollectionUtils.isNotEmpty(envCheckVos)) {
                envCheckVos.forEach(e -> {
                    if (StringUtils.isEmpty(e.getId())) {
                        e.setId(CodeTools.getCode32());
                    }
                    e.setPatrolId(patrolId);
                    e.setPatrolPointId(patrolPointId);
                });
                List<PatrolEnvCheckPo> envCheckPos = linePatrolConvertor.envCheckVosToPos(envCheckVos);
                envCheckPoList.addAll(envCheckPos);
            }
            //3.2 设备信息
            List<PatrolEquipmentVo> equipmentVos = p.getEquipmentVos();

            if (CollectionUtils.isNotEmpty(equipmentVos)) {
                equipmentVos.forEach(e -> {
                    if (StringUtils.isEmpty(e.getId())) {
                        e.setId(CodeTools.getCode32());
                    }
                    String patrolEquipmentId = e.getId();
                    e.setPatrolId(patrolId);
                    e.setPatrolPointId(patrolPointId);

                    //3.2.1 检查项信息
                    List<PatrolEquipmentItemPo> equipmentItemPos = e.getEquipmentItemPos();
                    if (CollectionUtils.isNotEmpty(equipmentItemPos)) {
                        equipmentItemPos.forEach(v -> {
                            if (StringUtils.isEmpty(v.getId())) {
                                v.setId(CodeTools.getCode32());
                            }
                            v.setPatrolId(patrolId);
                            v.setPatrolPointId(patrolPointId);
                            v.setPatrolEquipmentId(patrolEquipmentId);
                        });
                        equipmentItemPoList.addAll(equipmentItemPos);
                    }
                    //3.2.2 参数项信息
                    List<PatrolEquipmentParamsPo> equipmentParamsPos = e.getEquipmentParamsPos();
                    if (CollectionUtils.isNotEmpty(equipmentParamsPos)) {
                        equipmentParamsPos.forEach(v -> {
                            if (StringUtils.isEmpty(v.getId())) {
                                v.setId(CodeTools.getCode32());
                            }
                            v.setPatrolId(patrolId);
                            v.setPatrolPointId(patrolPointId);
                            v.setPatrolEquipmentId(patrolEquipmentId);
                        });
                        equipmentParamsPoList.addAll(equipmentParamsPos);
                    }

                });
                List<PatrolEquipmentPo> equipmentPos = linePatrolConvertor.equipmentVosToPos(equipmentVos);
                equipmentPoList.addAll(equipmentPos);
            }
        });

        List<PatrolPointPo> pointPos = linePatrolConvertor.pointVosToPo(pointVos);

        //开始入库
        //1.基础信息
        linePatrolService.insertOrUpdate(factory, patrolPo);
        patrolDto.setCode(patrolPo.getCode());
        //2.巡视人员
        linePatrolUserService.insertOrUpdateBatch(factory, userPos);
        //3.巡视点
        if (isInsert) {
            linePatrolPointService.insertBatch(factory, pointPos);
            //4.点位环境
            linePatrolEnvCheckService.insertBatch(factory, envCheckPoList);
            //5.设备信息
            linePatrolEquipmentService.insertBatch(factory, equipmentPoList);
            //6.检查项
            linePatrolEquipmentItemService.insertBatch(factory, equipmentItemPoList);
            //7.参数项
            linePatrolEquipmentParamsService.insertBatch(factory, equipmentParamsPoList);
        } else {
            linePatrolPointService.insertOrUpdateBatch(factory, pointPos);
            //4.点位环境
            linePatrolEnvCheckService.insertOrUpdateBatch(factory, envCheckPoList);
            //5.设备信息
            linePatrolEquipmentService.insertOrUpdateBatch(factory, equipmentPoList);
            //6.检查项
            linePatrolEquipmentItemService.insertOrUpdateBatch(factory, equipmentItemPoList);
            //7.参数项
            linePatrolEquipmentParamsService.insertOrUpdateBatch(factory, equipmentParamsPoList);
        }
        return patrolId;
    }


    @Override
    @TaskAnnotation("insertOrUpdateOther")
    public String insertOrUpdateOther(SessionFactory factory, PatrolDto patrolDto) {
        patrolDto.setOrderSource("other");
        Boolean updateFlag = true;
        List<PatrolEquipmentPo> equipmentPoList = new ArrayList<>();

        //1. 基础信息
        PatrolPo patrolPo = linePatrolConvertor.PatrolDtoToPo(patrolDto);
        if (StringUtils.isEmpty(patrolPo.getId())) {
            //巡视工单id为空 说明新建,后续所有的表主键都要重新赋值
            patrolPo.setId(CodeTools.getCode32());
            updateFlag = false;
        }
        //巡视工单id
        String patrolId = patrolPo.getId();

        //巡视工单签名信息
        if (patrolDto.getMustSign() != null && patrolDto.getMustSign() == 1) {
            //完成时必须签名
            List<OrderSignBean> signBeanList = patrolDto.getSignBeanList();
            if (CollectionUtils.isNotEmpty(signBeanList)) {
                for (OrderSignBean orderSignBean : signBeanList) {
                    orderSignBean.setOrderId(patrolId);
                    orderSignBean.setOrderType(OrderType.PATROL);
                }
                orderSignService.deleteByOrderId(factory, patrolId);
                orderSignService.insertBatch(factory, signBeanList);
            }
        }

        //2.巡视人员信息
        List<PatrolUserPo> userPos = patrolDto.getUserPos();
        if (CollectionUtils.isNotEmpty(userPos)) {
            userPos.forEach(p -> {
                if (StringUtils.isEmpty(p.getId())) {
                    p.setId(CodeTools.getCode32());
                }
                p.setPatrolId(patrolId);
            });
        }

        //3.巡视点信息
        List<PatrolPointVo> pointVos = patrolDto.getPointVos();
        Assert.notEmpty(pointVos, "巡视点不能为空");

        if (updateFlag) {
            //当更新的时候,根据更新的标记,修改要更新的清单,防止数据覆盖。
            PatrolDto patrolDto1Old = this.queryPatrolAllDtoByOrderId(factory, patrolId);
            List<PatrolPointVo> pointVosOld = patrolDto1Old.getPointVos();
            for (int i = 0; i < pointVos.size(); i++) {
                //不需要更新的，用旧数据替代
                if (!pointVos.get(i).getNeedUpdate()) {
                    for (PatrolPointVo patrolPointVoOld : pointVosOld) {
                        if (StringUtils.equalsIgnoreCase(patrolPointVoOld.getId(), pointVos.get(i).getId())) {
                            pointVos.set(i, patrolPointVoOld);
                            break;
                        }
                    }
                }
            }
        }

        pointVos.forEach(p -> {
            if (StringUtils.isEmpty(p.getId())) {
                p.setId(CodeTools.getCode32());
            }
            //设置默认巡视状态
            if (StringUtils.isEmpty(p.getStatus())) {
                p.setStatus(PatrolStatus.WAIT_PATROL.getStatus());
            }
            //设置默认签到状态
            if (Objects.isNull(p.getArriveStatus())) {
                p.setArriveStatus(0);
            }
            p.setPatrolId(patrolId);

            //巡视点id
            String patrolPointId = p.getId();
            //3.2 设备信息
            List<PatrolEquipmentVo> equipmentVos = p.getEquipmentVos();
            if (CollectionUtils.isNotEmpty(equipmentVos)) {
                equipmentVos.forEach(e -> {
                    if (StringUtils.isEmpty(e.getId())) {
                        e.setId(CodeTools.getCode32());
                    }
                    e.setPatrolId(patrolId);
                    e.setPatrolPointId(patrolPointId);
                });
                List<PatrolEquipmentPo> equipmentPos = linePatrolConvertor.equipmentVosToPos(equipmentVos);
                equipmentPoList.addAll(equipmentPos);
            }
        });

        List<PatrolPointPo> pointPos = linePatrolConvertor.pointVosToPo(pointVos);

        //开始入库
        //1.基础信息
        linePatrolService.insertOrUpdate(factory, patrolPo);
        patrolDto.setCode(patrolPo.getCode());
        //2.巡视人员
        linePatrolUserService.insertOrUpdateBatch(factory, userPos);
        //3.巡视点
        linePatrolPointService.insertOrUpdateBatch(factory, pointPos);
        //5.设备信息
        linePatrolEquipmentService.insertOrUpdateBatch(factory, equipmentPoList);
        return patrolId;
    }

    @Override
    @TaskAnnotation("queryVoPageList")
    public PageInfo<PatrolVo> queryVoPageList(SessionFactory factory, PatrolQuery query, PageQuery pageQuery) {
        pageQuery.getOrders().forEach(p -> {
            p.setPrefix("patrol");
        });
        PageHelper.startPage(pageQuery.getPage(), pageQuery.getPageSize(), pageQuery.getOrderBy());
        PatrolBusinessMapper mapper = factory.getMapper(PatrolBusinessMapper.class);

        List<PatrolVo> list = mapper.queryVoPageList(query);

        //分页后数据 进行查询巡视人员
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> patrolIds = list.stream().map(PatrolVo::getId).distinct().collect(Collectors.toList());
            List<PatrolUserPo> userPos = linePatrolUserService.queryByPatrolIds(factory, patrolIds);
            if (CollectionUtils.isNotEmpty(userPos)) {
                for (PatrolVo patrolVo : list) {
                    List<PatrolUserPo> userPoList = new ArrayList<>();
                    for (PatrolUserPo userPo : userPos) {
                        if (userPo.getPatrolId().equals(patrolVo.getId())) {
                            userPoList.add(userPo);
                        }
                    }
                    patrolVo.setUserPos(userPoList);
                }
            }
        }

        //对于还没有插入子数据的表修改其中的进度字段
        if (CollectionUtils.isNotEmpty(list)) {
            for (PatrolVo patrolVo : list) {
                if (patrolVo.getInsertFlag() == 1) {
                    //设置巡视点数量信息
                    patrolVo.setTotal(patrolVo.getPointNum());
                    patrolVo.setArriveStatusStep("0/" + patrolVo.getPointNum());
                    patrolVo.setStep("0/" + patrolVo.getPointNum());
                    //设置巡视人员信息
                    List<PatrolUserPo> userPos=JSON.parseArray(patrolVo.getPatrolUsers(), PatrolUserPo.class);
                    if (CollectionUtils.isNotEmpty(userPos)) {
                        patrolVo.setUserPos(userPos);
                    }

                }
            }
        }

        // PageInfo pageInfo = new PageInfo();
        // list.sort(Comparator.comparing(o -> idsIndexMap.get(o.getId())));
        // pageInfo.setList(list);
        // return pageInfo;
        return new PageInfo<>(list);
    }

    @Override
    @TaskAnnotation("queryPatrolDtoByOrderId")
    public PatrolDto queryPatrolDtoByOrderId(SessionFactory factory, String orderId) {
        //查询巡视基础信息
        PatrolBaseVo patrolBaseVo = queryByOrderId(factory, orderId);
        //转换
        PatrolDto dto = linePatrolConvertor.patrolBaseVoToDto(patrolBaseVo);

        //查询工单下的点位列表
        PatrolPointPo patrolPointPo = new PatrolPointPo();
        patrolPointPo.setPatrolId(orderId);
        List<PatrolPointPo> pointPos = linePatrolPointService.queryList(factory, patrolPointPo);

        //todo 原先处理 先查询点位ids 然后根据id去查询 比较耗时,现改为一次性查询
        List<PatrolPointVo> pointVos = queryPatrolPointVoByPatrolId(factory, orderId);

        if (pointVos != null) {
            List<PatrolEquipmentVo> equipmentVos = pointVos.stream()
                    .map(PatrolPointVo::getEquipmentVos)
                    .flatMap(Collection::stream)
                    .collect(Collectors.toList());
            fillLatLong(equipmentVos);
        }

        //点位id查询巡视情况
        /*List<PatrolPointVo> pointVos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(pointPos)) {
            pointPos.forEach(p -> {
                String id = p.getId();
                PatrolPointVo pointVo = queryByPatrolPointId(factory, id);
                if (!Objects.isNull(pointVo)) {
                    pointVos.add(pointVo);
                }
            });
            dto.setPointVos(pointVos);
        }*/
        dto.setPointVos(pointVos);
        return dto;
    }

    // 填充经纬度
    private void fillLatLong(List<PatrolEquipmentVo> equipmentVoList) {
        if (CollectionUtils.isEmpty(equipmentVoList)) {
            return;
        }
        String firstLatitude = equipmentVoList.stream().findFirst().map(PatrolEquipmentVo::getLatitude).orElse(null);
        if (firstLatitude != null) {
            return;
        }
        List<String> equipmentIds = equipmentVoList.stream().map(PatrolEquipmentPo::getEquipmentId).collect(Collectors.toList());
        Map<String, Map<String, String>> paramsMap = equipmentFeign.getTowerParams(equipmentIds).getData();
        if (paramsMap == null || paramsMap.size() == 0) {
            return;
        }
        for (PatrolEquipmentVo patrolEquipmentVo : equipmentVoList) {
            Map<String, String> map = paramsMap.get(patrolEquipmentVo.getEquipmentId());
            if (map == null || map.size() == 0) {
                continue;
            }
            patrolEquipmentVo.setLongitude(map.getOrDefault("longitude", null));
            patrolEquipmentVo.setLatitude(map.getOrDefault("latitude", null));
        }
    }

    @Override
    @TaskAnnotation("queryPatrolPointVoByPatrolId")
    public List<PatrolPointVo> queryPatrolPointVoByPatrolId(SessionFactory factory, String orderId) {
        PatrolBusinessMapper mapper = factory.getMapper(PatrolBusinessMapper.class);
        //sql查询巡视点位列表信息
        List<PatrolPointVo> patrolPointVos = mapper.queryPatrolPointVoByPatrolId(orderId);

        if (CollectionUtils.isEmpty(patrolPointVos)) {
            return new ArrayList<>();
        }

        List<String> equipmentIds = new ArrayList<>();
        //第一次循环将 设备id收集
        for (PatrolPointVo patrolPointVo : patrolPointVos) {
            List<PatrolEquipmentVo> equipmentVos = patrolPointVo.getEquipmentVos();
            if (CollectionUtils.isEmpty(equipmentVos)) {
                continue;
            }
            //查询设备的缺陷数

            for (PatrolEquipmentVo equipmentVo : equipmentVos) {

                equipmentIds.add(equipmentVo.getEquipmentId());

            }
        }

        fillLatLong(patrolPointVos.stream()
                .map(PatrolPointVo::getEquipmentVos)
                .flatMap(Collection::stream)
                .collect(Collectors.toList()));

        //查询设备ids的缺陷数
        List<DefectEquipmentDto> defectEquipmentDtos = defectService.queryEquipmentDefectNumsByIds(factory, equipmentIds);

        if (CollectionUtils.isNotEmpty(defectEquipmentDtos)) {

            //转map方便取值
            Map<String, Integer> equip_cond = defectEquipmentDtos.stream().collect(Collectors.toMap(DefectEquipmentDto::getEquipmentId, DefectEquipmentDto::getNum));

            for (PatrolPointVo patrolPointVo : patrolPointVos) {
                List<PatrolEquipmentVo> equipmentVos = patrolPointVo.getEquipmentVos();
                if (CollectionUtils.isEmpty(equipmentVos)) {
                    continue;
                }
                //赋值
                for (PatrolEquipmentVo equipmentVo : equipmentVos) {
                    equipmentVo.setCurrDefect(equip_cond.getOrDefault(equipmentVo.getEquipmentId(), 0));
                }
            }
        }

        return patrolPointVos;
    }

    @Override
    @TaskAnnotation("queryPatrolAllDtoByOrderId")
    public PatrolDto queryPatrolAllDtoByOrderId(SessionFactory factory, String orderId) {

        //根据orderId查询  同计划下,上一个工单数据
        PatrolDto dto = queryPatrolDtoByOrderId(factory, orderId);

        String planId = dto.getPlanId();
        Date planStartTime = dto.getPlanStartTime();
        String preOrderId = null;

        PatrolQuery patrolQuery = new PatrolQuery();
        patrolQuery.setPlanId(planId);
        patrolQuery.setPlanStartTime(dto.getPlanStartTime());

        PageQuery pageQuery = new PageQuery();
        pageQuery.getOrders().add(new OrderItem("plan_start_time", false));
        pageQuery.getOrders().forEach(e -> e.setPrefix("patrol"));

        PageInfo<PatrolPo> pageInfo = linePatrolService.queryPageList(factory, patrolQuery, pageQuery);
        List<PatrolPo> list = pageInfo.getList();

        if (CollectionUtils.isNotEmpty(list)) {
            for (PatrolPo patrolPo : list) {

                if (patrolPo.getPlanStartTime() != null && planStartTime != null && patrolPo.getPlanStartTime().getTime() < planStartTime.getTime()) {
                    preOrderId = patrolPo.getId();
                    break;
                }
            }
            if (StringUtils.isNotEmpty(preOrderId)) {
                PatrolDto preDto = queryPatrolDtoByOrderId(factory, preOrderId);

                Map<String, EquipmentHisDto> cond = new HashMap<>();

                List<PatrolPointVo> prePointVos = preDto.getPointVos();
                for (PatrolPointVo pointVo : prePointVos) {
                    List<PatrolEquipmentVo> equipmentVos = pointVo.getEquipmentVos();
                    for (PatrolEquipmentVo equipmentVo : equipmentVos) {
                        String equipmentId = equipmentVo.getEquipmentId();
                        cond.put(equipmentId, new EquipmentHisDto(equipmentVo.getRemarks(), equipmentVo.getResult(), equipmentVo.getStatus()));
                    }
                }
                if (MapUtils.isNotEmpty(cond)) {
                    List<PatrolPointVo> pointVos = dto.getPointVos();
                    for (PatrolPointVo pointVo : pointVos) {
                        List<PatrolEquipmentVo> equipmentVos = pointVo.getEquipmentVos();
                        for (PatrolEquipmentVo equipmentVo : equipmentVos) {
                            String equipmentId = equipmentVo.getEquipmentId();
                            EquipmentHisDto equipmentHisDto = cond.get(equipmentId);
                            if (!Objects.isNull(equipmentHisDto)) {
                                equipmentVo.setResult_his(equipmentHisDto.getResult());
                                equipmentVo.setRemarks_his(equipmentHisDto.getRemarks());
                                equipmentVo.setStatus_his(equipmentHisDto.getStatus());
                            }
                        }
                    }
                }
            }
        }
        if (dto.getPointVos() != null) {
            fillLatLong(dto.getPointVos().stream()
                    .map(PatrolPointVo::getEquipmentVos)
                    .flatMap(Collection::stream)
                    .collect(Collectors.toList()));
        }
        return dto;

    }

    @Override
    @TaskAnnotation("queryByOrderId")
    public PatrolBaseVo queryByOrderId(SessionFactory factory, String orderId) {
        if(!this.checkCreatePatrolDetail(factory, orderId)) return null;
        //查询各个环节数据组装
        PatrolPo patrolPo = linePatrolService.queryById(factory, orderId);

        PatrolBaseVo patrolBaseVo = linePatrolConvertor.patrolPoToBaseVo(patrolPo);

        List<PatrolUserPo> userPos = linePatrolUserService.queryByPatrolId(factory, orderId);

        patrolBaseVo.setUserPos(userPos);

        //完成时必须签名
        if (patrolBaseVo.getMustSign() != null && patrolBaseVo.getMustSign() == 1) {
            OrderSignBean orderSignBean = new OrderSignBean();
            orderSignBean.setOrderId(orderId);
            List<OrderSignBean> signBeanList = orderSignService.queryList(factory, orderSignBean);
            patrolBaseVo.setSignBeanList(signBeanList);
        }

        return patrolBaseVo;

    }

    @Override
    @TaskAnnotation("queryByPatrolPointId")
    public PatrolPointVo queryByPatrolPointId(SessionFactory factory, String patrolPointId) {

        //1.点位信息
        PatrolPointPo patrolPointPo = linePatrolPointService.queryById(factory, patrolPointId);

        PatrolPointVo patrolPointVo = linePatrolConvertor.patrolPointPoToVo(patrolPointPo);

        //2.环境检查信息
        List<PatrolEnvCheckPo> envCheckPos = linePatrolEnvCheckService.queryByPatrolPointId(factory, patrolPointId);

        List<PatrolEnvCheckVo> envCheckVos = linePatrolConvertor.envCheckPosToVos(envCheckPos);

        patrolPointVo.setEnvCheckVos(envCheckVos);

        //3.设备信息
        List<PatrolEquipmentPo> equipmentPos = linePatrolEquipmentService.queryByPatrolPointId(factory, patrolPointId);
        List<PatrolEquipmentVo> equipmentVos = linePatrolConvertor.equipmentPosToVos(equipmentPos);

        if (!CollectionUtils.isEmpty(equipmentVos)) {
            equipmentVos.forEach(p -> {

                //3.1 检查项
                List<PatrolEquipmentItemPo> patrolEquipmentItemPos = linePatrolEquipmentItemService.queryByPatrolEquipmentId(factory, p.getId());
                p.setEquipmentItemPos(patrolEquipmentItemPos);

                //3.2 参数项
                List<PatrolEquipmentParamsPo> patrolEquipmentParamsPos = linePatrolEquipmentParamsService.queryByPatrolEquipmentId(factory, p.getId());
                p.setEquipmentParamsPos(patrolEquipmentParamsPos);

                //3.3 当前设备缺陷数量
                DefectQuery defectQuery = new DefectQuery();
                defectQuery.setEquipmentId(p.getEquipmentId());
                List<DefectBean> defectBeans = defectService.queryList(factory, defectQuery);
                if (CollectionUtils.isEmpty(defectBeans)) {
                    p.setCurrDefect(0);
                } else {
                    List<DefectBean> collect = defectBeans.stream().filter(v -> v.getFactEndTime() != null).collect(Collectors.toList());
                    p.setCurrDefect(CollectionUtils.isEmpty(collect) ? 0 : collect.size());
                }
            });
            fillLatLong(equipmentVos);
        }

        patrolPointVo.setEquipmentVos(equipmentVos);

        return patrolPointVo;
    }



    @SneakyThrows
    @Override
    @TaskAnnotation("insertPatrolUser")
    public String insertPatrolUser(SessionFactory factory, PatrolDto patrolDto){
        //1. 基础信息
        PatrolPo patrolPo = linePatrolConvertor.PatrolDtoToPo(patrolDto);
        if (StringUtils.isEmpty(patrolPo.getId())) {
            //巡视工单id为空 说明新建,后续所有的表主键都要重新赋值
            patrolPo.setId(CodeTools.getCode32());
        }
        //巡视工单id
        String patrolId = patrolPo.getId();

        //2.巡视人员信息
        List<PatrolUserPo> userPos = patrolDto.getUserPos();
        if (CollectionUtils.isNotEmpty(userPos)) {
            patrolPo.setPatrolUsers(JSON.toJSONString(userPos));
      /*      userPos.forEach(p -> {
                if (StringUtils.isEmpty(p.getId())) {
                    p.setId(CodeTools.getCode32());
                }
                p.setPatrolId(patrolId);
            });*/
        }

        //开始入库
        //1.基础信息
        linePatrolService.insertOrUpdate(factory, patrolPo);
        patrolDto.setCode(patrolPo.getCode());              // 编码回填
        //2.巡视人员
        //linePatrolUserService.insertOrUpdateBatch(factory, userPos);
        return patrolId;
    }

    public Boolean checkCreatePatrolDetail(SessionFactory factory, String orderId) {
        //判断子数据有没有生成,没有生成的时候生成子数据
        PatrolPo patrolPo = linePatrolService.queryById(factory, orderId);
        if(patrolPo==null) return false;
        if(patrolPo.getInsertFlag()!=1){
            return true;
        }else {
            try {
                PatrolDto planPatrolMsg =  CommonUtils.ok(planLineOrderMsgFeign.getPlanPatrolMsg(patrolPo.getPlanId(), DateUtils.getString(patrolPo.getCreateTime(),"yyyy-MM-dd HH:mm")));
                this.insertPatrolDetail(factory,  planPatrolMsg, orderId,patrolPo.getPatrolUsers());
                return true;
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                return false;
            }
        }
    }



    public String insertPatrolDetail(SessionFactory factory, PatrolDto patrolDto, String oderId, String patrolUsers){
        List<PatrolEnvCheckPo> envCheckPoList = new ArrayList<>();
        List<PatrolEquipmentPo> equipmentPoList = new ArrayList<>();
        List<PatrolEquipmentItemPo> equipmentItemPoList = new ArrayList<>();
        List<PatrolEquipmentParamsPo> equipmentParamsPoList = new ArrayList<>();
        //1. 基础信息
        PatrolPo patrolPo = linePatrolConvertor.PatrolDtoToPo(patrolDto);
        patrolPo.setId(oderId);
        //巡视工单id
        String patrolId = patrolPo.getId();

        //巡视工单签名信息
        if (patrolDto.getMustSign()!=null && patrolDto.getMustSign()==1) {
            //完成时必须签名
            List<OrderSignBean> signBeanList = patrolDto.getSignBeanList();
            if (CollectionUtils.isNotEmpty(signBeanList)) {
                for (OrderSignBean orderSignBean : signBeanList) {
                    orderSignBean.setOrderId(patrolId);
                    orderSignBean.setOrderType(OrderType.PATROL);
                }
                orderSignService.deleteByOrderId(factory,patrolId);
                orderSignService.insertBatch(factory,signBeanList);
            }
        }

        //2.巡视人员信息
        //List<PatrolUserPo> userPos = patrolDto.getUserPos();
        List<PatrolUserPo> userPos=JSON.parseArray(patrolUsers, PatrolUserPo.class);
        if (CollectionUtils.isNotEmpty(userPos)) {
            userPos.forEach(p -> {
                if (StringUtils.isEmpty(p.getId())) {
                    p.setId(CodeTools.getCode32());
                }
                p.setPatrolId(patrolId);
            });
        }
        //3.巡视点信息
        List<PatrolPointVo> pointVos = patrolDto.getPointVos();
        Assert.notEmpty(pointVos, "巡视点不能为空");

        pointVos.forEach(p -> {
            if (StringUtils.isEmpty(p.getId())) {
                p.setId(CodeTools.getCode32());
            }
            //设置默认巡视状态
            if (StringUtils.isEmpty(p.getStatus())) {
                p.setStatus(PatrolStatus.WAIT_PATROL.getStatus());
            }
            //设置默认签到状态
            if (Objects.isNull(p.getArriveStatus())) {
                p.setArriveStatus(0);
            }
            p.setPatrolId(patrolId);

            //巡视点id
            String patrolPointId = p.getId();
            //3.1 环境检查信息
            List<PatrolEnvCheckVo> envCheckVos = p.getEnvCheckVos();
            if (CollectionUtils.isNotEmpty(envCheckVos)) {
                envCheckVos.forEach(e -> {
                    if (StringUtils.isEmpty(e.getId())) {
                        e.setId(CodeTools.getCode32());
                    }
                    e.setPatrolId(patrolId);
                    e.setPatrolPointId(patrolPointId);
                });
                List<PatrolEnvCheckPo> envCheckPos = linePatrolConvertor.envCheckVosToPos(envCheckVos);
                envCheckPoList.addAll(envCheckPos);
            }
            //3.2 设备信息
            List<PatrolEquipmentVo> equipmentVos = p.getEquipmentVos();

            if (CollectionUtils.isNotEmpty(equipmentVos)) {
                equipmentVos.forEach(e -> {
                    if (StringUtils.isEmpty(e.getId())) {
                        e.setId(CodeTools.getCode32());
                    }
                    String patrolEquipmentId = e.getId();
                    e.setPatrolId(patrolId);
                    e.setPatrolPointId(patrolPointId);

                    //3.2.1 检查项信息
                    List<PatrolEquipmentItemPo> equipmentItemPos = e.getEquipmentItemPos();
                    if (CollectionUtils.isNotEmpty(equipmentItemPos)) {
                        equipmentItemPos.forEach(v -> {
                            if (StringUtils.isEmpty(v.getId())) {
                                v.setId(CodeTools.getCode32());
                            }
                            v.setPatrolId(patrolId);
                            v.setPatrolPointId(patrolPointId);
                            v.setPatrolEquipmentId(patrolEquipmentId);
                        });
                        equipmentItemPoList.addAll(equipmentItemPos);
                    }
                    //3.2.2 参数项信息
                    List<PatrolEquipmentParamsPo> equipmentParamsPos = e.getEquipmentParamsPos();
                    if (CollectionUtils.isNotEmpty(equipmentParamsPos)) {
                        equipmentParamsPos.forEach(v -> {
                            if (StringUtils.isEmpty(v.getId())) {
                                v.setId(CodeTools.getCode32());
                            }
                            v.setPatrolId(patrolId);
                            v.setPatrolPointId(patrolPointId);
                            v.setPatrolEquipmentId(patrolEquipmentId);
                        });
                        equipmentParamsPoList.addAll(equipmentParamsPos);
                    }

                });
                List<PatrolEquipmentPo> equipmentPos = linePatrolConvertor.equipmentVosToPos(equipmentVos);
                equipmentPoList.addAll(equipmentPos);
            }
        });

        List<PatrolPointPo> pointPos = linePatrolConvertor.pointVosToPo(pointVos);

        //开始入库
        //1.基础信息
        patrolPo.setInsertFlag(0);
        linePatrolService.updatePatrolInsertFlag(factory, patrolPo);
        //2.巡视人员
        linePatrolUserService.insertOrUpdateBatch(factory, userPos);
        //3.巡视点
        linePatrolPointService.insertOrUpdateBatch(factory, pointPos);
        //4.点位环境
        linePatrolEnvCheckService.insertOrUpdateBatch(factory, envCheckPoList);
        //5.设备信息
        linePatrolEquipmentService.insertOrUpdateBatch(factory, equipmentPoList);
        //6.检查项
        linePatrolEquipmentItemService.insertOrUpdateBatch(factory, equipmentItemPoList);
        //7.参数项
        linePatrolEquipmentParamsService.insertOrUpdateBatch(factory, equipmentParamsPoList);

        return patrolId;
    }


    @Override
    @TaskAnnotation("queryVoList")
    public List<PatrolExportVo> queryVoList(SessionFactory factory, PatrolQuery query) {
        PatrolBusinessMapper patrolBusinessMapper = factory.getMapper(PatrolBusinessMapper.class);
        List<PatrolVo> list = patrolBusinessMapper.queryVoPageList(query);
        list.stream().forEach(patrolVo -> {
                    if (patrolVo.getInsertFlag() == 1) {
                        try {
                            PatrolDto planPatrolMsg = CommonUtils.ok(planLineOrderMsgFeign.getPlanPatrolMsg(patrolVo.getPlanId(), DateUtils.getString(patrolVo.getCreateTime(), "yyyy-MM-dd HH:mm")));
                            this.insertPatrolDetail(factory, planPatrolMsg, patrolVo.getId(), patrolVo.getPatrolUsers());
                        } catch (Exception e) {
                            log.error(e.getMessage(),e);
                        }
                    }
                }
        );
        PatrolBusinessMapper mapper = factory.getMapper(PatrolBusinessMapper.class);
        List<String> orderIds = list.stream().map(PatrolVo::getId).collect(Collectors.toList());

        //sql查询巡视点位列表信息
        List<PatrolPointVo> patrolPointVos = mapper.queryPatrolPointVoByPatrolIds(orderIds);

        if (CollectionUtils.isEmpty(patrolPointVos)) {
            return new ArrayList<>();
        }
        List<PatrolExportVo> patrolExportVoList = new ArrayList<>();
        AtomicInteger count = new AtomicInteger();
        patrolPointVos.forEach(p -> {
            if (CollectionUtils.isNotEmpty(p.getEquipmentVos())) {
                p.getEquipmentVos().forEach(equipmentVo -> {
                    if (p.getId().equals(equipmentVo.getPatrolPointId())) {
                        //3.1 检查项
                        List<PatrolEquipmentItemPo> patrolEquipmentItemPos = linePatrolEquipmentItemService.queryByPatrolEquipmentId(factory, equipmentVo.getId());
                        equipmentVo.setEquipmentItemPos(patrolEquipmentItemPos);

                        //3.2 参数项
                        List<PatrolEquipmentParamsPo> patrolEquipmentParamsPos = linePatrolEquipmentParamsService.queryByPatrolEquipmentId(factory, equipmentVo.getId());
                        equipmentVo.setEquipmentParamsPos(patrolEquipmentParamsPos);

                        PatrolExportVo patrolExportVo = new PatrolExportVo();
                        PatrolVo patrolVo1 = list.stream().filter(patrolVo -> p.getPatrolId().equals(patrolVo.getId())).findFirst().get();
                        patrolExportVo.setCode(patrolVo1.getCode());
                        patrolExportVo.setTitle(patrolVo1.getTitle());
                        patrolExportVo.setId(count.getAndIncrement());
                        patrolExportVo.setWorkTime(DateUtil.format(p.getWorkTime(), "yyyy-MM-dd HH:mm:ss"));
                        patrolExportVo.setWorkerName(p.getWorkerName());
                        patrolExportVo.setRemarks(equipmentVo.getRemarks());
                        patrolExportVo.setStatus(p.getStatus());
                        patrolExportVo.setArriveStatus(p.getArriveStatus() + "");
                        patrolExportVo.setName(p.getName());
                        patrolExportVo.setEquipmentName(equipmentVo.getName());
                        patrolExportVo.setNameAndUnit(convertor(patrolEquipmentParamsPos));
                        patrolExportVo.setResult(equipmentVo.getResult() + "");
                        patrolExportVo.setRunStatus(equipmentVo.getStatus() + "");
                        patrolExportVo.setCheckName(convertorToCheckName(patrolEquipmentItemPos)[0] == null ? "-" : convertorToCheckName(patrolEquipmentItemPos)[0]);
                        patrolExportVo.setStandardName(convertorToCheckName(patrolEquipmentItemPos)[1] == null ? "-" : convertorToCheckName(patrolEquipmentItemPos)[1]);
                        patrolExportVoList.add(patrolExportVo);
                    }
                });
            }
        });
        return patrolExportVoList;
    }

    private String convertor(List<PatrolEquipmentParamsPo> patrolEquipmentParamsPos) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtils.isNotEmpty(patrolEquipmentParamsPos)) {
            int count = 1;
            for (PatrolEquipmentParamsPo patrolEquipmentParamsPo : patrolEquipmentParamsPos) {
                sb.append(count + "、" + patrolEquipmentParamsPo.getName() + ":" + (patrolEquipmentParamsPo.getValue() == null ? "" : patrolEquipmentParamsPo.getValue()) + " " + patrolEquipmentParamsPo.getUnit()).append(";");
                count++;
            }
        }
        return sb.toString();
    }

    private String[] convertorToCheckName(List<PatrolEquipmentItemPo> patrolEquipmentItemPos) {
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        if (CollectionUtils.isNotEmpty(patrolEquipmentItemPos)) {
            int count = 1;
            for (PatrolEquipmentItemPo patrolEquipmentItemPo : patrolEquipmentItemPos) {
                sb1.append(count + "、" + patrolEquipmentItemPo.getCheckName()).append(";").append("\r");
                sb2.append(count + "、" + patrolEquipmentItemPo.getStandardName()).append(";").append("\r");
                count++;
            }
        }
        return new String[]{sb1.toString(),sb2.toString()};
    }
}
